using System;
#if (!SILVERLIGHT)
using System.Collections;
#endif
using System.Collections.Generic;
using NUnit.Framework;

namespace ValidationFramework.Tests
{
    public class EnumerableDuplicateRuleTest
    {

        const string expectedErrorMessage = "expectedErrorMessage";
        const string expectedRuleSet = "EXPECTEDRULESET";

        [TestFixture]
        public class Construction
        {
            [Test]
            public void Simple1()
            {
                var rule = new EnumerableDuplicateRule(expectedErrorMessage, expectedRuleSet, false, StringComparer.Ordinal);
                Assert.AreEqual(expectedErrorMessage, rule.ErrorMessage);
                Assert.AreEqual(StringComparer.Ordinal, rule.Comparer);
                Assert.IsFalse(rule.UseErrorMessageProvider);
            }


            [Test]
            public void Simple2()
            {
                var rule = new EnumerableDuplicateRule(expectedErrorMessage);
                Assert.AreEqual(expectedErrorMessage, rule.ErrorMessage);
                Assert.IsNull(rule.Comparer);
                Assert.IsFalse(rule.UseErrorMessageProvider);
            }


            [Test]
            public void Simple3()
            {
                var rule = new EnumerableDuplicateRule();
                Assert.IsNull(rule.ErrorMessage);
                Assert.IsNull(rule.Comparer);
                Assert.IsFalse(rule.UseErrorMessageProvider);
            }

        }


        [TestFixture]
        public class Validate
        {
            [Test]
            public void Generic()
            {
                var rule = new EnumerableDuplicateRule(null, null, false, null);
                List<int> list = null;
                Assert.IsNull(rule.Validate(null, list, null, null));

                list = new List<int>();
                Assert.IsNull(rule.Validate(null, list, null, null));

                list.Add(1);
                Assert.IsNull(rule.Validate(null, list, null, null));

                list.Add(1);
                Assert.IsNotNull(rule.Validate(null, list, null, null));
            }
#if(!SILVERLIGHT)
            [Test]
            public void NonGeneric()
            {

                var rule = new EnumerableDuplicateRule(null, null, false, null);
                ArrayList list = null;
                Assert.IsNull(rule.Validate(null, list, null, null));

                list = new ArrayList();
                Assert.IsNull(rule.Validate(null, list, null, null));

                list.Add(1);
                Assert.IsNull(rule.Validate(null, list, null, null));

                list.Add(1);
                Assert.IsNotNull(rule.Validate(null, list, null, null));

            }
#endif
        }


        [TestFixture]
        public class IsEquivalent
        {
            [Test]
            public void Equality()
            {
                var rule1 = new EnumerableDuplicateRule(null, null, false, null);
                var rule2 = new EnumerableDuplicateRule(null, null, false, null);

                Assert.IsTrue(rule1.IsEquivalent(rule2));

            }
        }


        [TestFixture]
        public class RuleInterpretation
        {
            [Test]
            public void RuleRuleInterpretation()
            {
                var rule = new EnumerableDuplicateRule(null, null, false, null);
                Assert.IsNotNull(rule.RuleInterpretation);
            }
        }


        [TestFixture]
        public class CheckTypes
        {
            [Test]
            public void Simple()
            {
                var rule = new EnumerableDuplicateRule(null, null, false, null);
            			rule.CheckType(new MockInfoDescriptor(typeof (IList<int>).TypeHandle, "foo"));
                rule = new EnumerableDuplicateRule(null, null, false, null);
            			rule.CheckType(new MockInfoDescriptor(typeof (List<int>).TypeHandle, "foo"));
                rule = new EnumerableDuplicateRule(null, null, false, null);
                rule.CheckType(new MockInfoDescriptor(typeof(ICollection<int>).TypeHandle, "foo"));
                rule = new EnumerableDuplicateRule(null, null, false, null);
            			rule.CheckType(new MockInfoDescriptor(typeof (LinkedList<int>).TypeHandle, "foo"));
                rule = new EnumerableDuplicateRule(null, null, false, null);
            			rule.CheckType(new MockInfoDescriptor(typeof (Stack<int>).TypeHandle, "foo"));
#if (!SILVERLIGHT)
                rule = new EnumerableDuplicateRule(null, null, false, null);
            			rule.CheckType(new MockInfoDescriptor(typeof (ArrayList).TypeHandle, "foo"));
#endif
                rule = new EnumerableDuplicateRule(null, null, false, null);
            			rule.CheckType(new MockInfoDescriptor(typeof (string).TypeHandle, "foo"));
                rule = new EnumerableDuplicateRule(null, null, false, null);
                rule.CheckType(new MockInfoDescriptor(typeof (int[]).TypeHandle, "foo"));
            }


        	[Test]
            [ExpectedException(typeof(ArgumentException), ExpectedMessage = "Member 'foo' must be a 'System.Collections.IEnumerable' to be used for the ValidationFramework.EnumerableDuplicateRule. Actual Type 'System.Int32'.\r\nParameter name: value")]
            public void ExceptionInvalidType()
            {
                var rule = new EnumerableDuplicateRule(null, null, false, null);
        	    rule.CheckType(new MockInfoDescriptor(typeof (int).TypeHandle, "foo"));
            }
        }

    }
}